﻿using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Attributes;
using nERP.Model;
using System.Collections.Generic;
using WalkingTec.Mvvm.Core.Extensions;
using WalkingTec.Mvvm.Core.Models;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using nERP.Model.Bas;
using nERP.Model.Po;
using nERP.Model.So;
using nERP.Model.Wms;
using nERP.Model.Fin;
using nERP.Model._Admin;
using nERP.Model.Rpt;

namespace nERP.DataAccess
{
    public partial class DataContext : FrameworkContext
    {
        public DbSet<FrameworkUser> FrameworkUsers { get; set; }
        public DbSet<Supplier> Suppliers { get; set; }
        public DbSet<Warehouse> Warehouses { get; set; }
        public DbSet<Customer> Customers { get; set; }
        public DbSet<SettlementAccount> SettlementAccounts { get; set; }
        public DbSet<Goods> Goodss { get; set; }
        public DbSet<GoodsClass> GoodsClasss { get; set; }
        public DbSet<ComputationUnit> ComputationUnits { get; set; }
        public DbSet<Buy> Buys { get; set; }
        public DbSet<BuyDetail> BuyDetails { get; set; }
        public DbSet<BuyReturn> BuyReturns { get; set; }
        public DbSet<BuyReturnDetail> BuyReturnDetails { get; set; }
        public DbSet<Sale> Sales { get; set; }
        public DbSet<SaleDetail> SaleDetails { get; set; }
        public DbSet<SaleReturn> SaleReturns { get; set; }
        public DbSet<SaleReturnDetail> SaleReturnDetails { get; set; }
        public DbSet<BuyInWarehouse> BuyInWarehouses { get; set; }
        public DbSet<BuyInWarehouseDetail> BuyInWarehouseDetails { get; set; }
        public DbSet<BuyReturnOutWarehouse> BuyReturnOutWarehouses { get; set; }
        public DbSet<BuyReturnOutWarehouseDetail> BuyReturnOutWarehouseDetails { get; set; }
        public DbSet<SaleOutWarehouse> SaleOutWarehouses { get; set; }
        public DbSet<SaleOutWarehouseDetail> SaleOutWarehouseDetails { get; set; }
        public DbSet<SaleReturnInWarehouse> SaleReturnInWarehouses { get; set; }
        public DbSet<SaleReturnInWarehouseDetail> SaleReturnInWarehouseDetails { get; set; }
        public DbSet<OtherInWarehouse> OtherInWarehouses { get; set; }
        public DbSet<OtherOutWarehouse> OtherOutWarehouses { get; set; }
        public DbSet<OtherInWarehouseDetail> OtherInWarehouseDetails { get; set; }
        public DbSet<OtherOutWarehouseDetail> OtherOutWarehouseDetails { get; set; }
        public DbSet<Receivable> Receivables { get; set; }
        public DbSet<ReceivableDetail> ReceivableDetails { get; set; }
        public DbSet<Payment> Payments { get; set; }
        public DbSet<PaymentDetail> PaymentDetails { get; set; }
        public DbSet<OtherIncome> OtherIncomes { get; set; }
        public DbSet<OtherOutlay> OtherOutlays { get; set; }
        public DbSet<CodingList> CodingLists { get; set; }
        public DbSet<CodingRule> CodingRules { get; set; }
        public DbSet<Dashboard> Dashboards { get; set; }
        public DbSet<DicDef> DicDefs { get; set; }
        public DbSet<DicField> DicFields { get; set; }
        public DbSet<FrameworkUserRole> FrameworkUserRoles { get; set; }
        public DbSet<FrameworkUserGroup> FrameworkUserGroups { get; set; }

        public DataContext(CS cs)
             : base(cs)
        {
        }

        public DataContext(string cs, DBTypeEnum dbtype) : base(cs, dbtype)
        {

        }

        public DataContext(string cs, DBTypeEnum dbtype, string version = null) : base(cs, dbtype, version)
        {

        }
        public DataContext(DbContextOptions<DataContext> options) : base(options) { }

        public override async Task<bool> DataInit(object allModules, bool IsSpa)
        {
            var state = await base.DataInit(allModules, IsSpa);
            bool emptydb = false;
            try
            {
                emptydb = Set<FrameworkUser>().Count() == 0 && Set<FrameworkUserRole>().Count() == 0;
            }
            catch { }
            if (state == true || emptydb == true)
            {
                //when state is true, means it's the first time EF create database, do data init here
                //当state是true的时候，表示这是第一次创建数据库，可以在这里进行数据初始化
                var user = new FrameworkUser { ITCode = "admin", Password = Utils.GetMD5String("000000"), IsValid = true, Name = "Admin", };
                var userrole = new FrameworkUserRole { UserCode = user.ITCode, RoleCode = "001" };
                var adminmenus = Set<FrameworkMenu>().Where(x => x.Url != null && x.Url.StartsWith("/api") == false).ToList();
                foreach (var item in adminmenus) { item.Url = "/_admin" + item.Url; }
                Set<FrameworkUser>().Add(user);
                Set<FrameworkUserRole>().Add(userrole);
                #region 自定义初始化数据 2024-08-23

                string Code = "通用";
                string Code2 = "客户";//客户：K+年最后一位+6位流水
                string Code3 = "供应商";//供应商：G+年最后一位+6位流水
                string Code4 = "采购订单";//采购订单：PO-XX+yyyyMMdd+5位流水
                string Code5 = "采购退货";//采购退货：POR-XX+yyyyMMdd+5位流水
                string Code6 = "销售订单";//销售订单：SO-XX+yyyyMMdd+5位流水
                string Code7 = "销售退货";//采购退货：SOR-XX+yyyyMMdd+5位流水
                string Code8 = "采购入库";//采购入库：RK+yyyyMMdd+5位流水
                string Code9 = "采购退货出库";//采购退货出库：RKR+yyyyMMdd+5位流水
                string Code10 = "销售出库";//销售出库：CK+yyyyMMdd+5位流水
                string Code11 = "销售退货入库";//销售退货入库：CKR+yyyyMMdd+5位流水
                string Code12 = "其他入库";//其他入库：ORK+yyyyMMdd+5位流水
                string Code13 = "其他出库";//其他出库：OCK+yyyyMMdd+5位流水
                string Code14 = "收款单";//收款单：SK+yyyyMMdd+5位流水
                string Code15 = "付款单";//付款单：FK+yyyyMMdd+5位流水
                string Code16 = "其他收入";//其他收入：OSK+yyyyMMdd+5位流水
                string Code17 = "其他支出";//其他支出：OFK+yyyyMMdd+5位流水

                List<CodingList> codinglist = new List<CodingList>(){
                    new CodingList() { ID = Guid.NewGuid(), Code = Code, CurrentNumber = 0, IsValid = true, CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code2, CurrentNumber = 0, IsValid = true, CreateBy="Admin",CreateTime=DateTime.Now  },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code3, CurrentNumber = 0, IsValid = true, CreateBy="Admin",CreateTime=DateTime.Now  },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code4, CurrentNumber = 0, IsValid = true,  CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code5, CurrentNumber = 0, IsValid = true,  CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code6, CurrentNumber = 0, IsValid = true,  CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code7, CurrentNumber = 0, IsValid = true,  CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code8, CurrentNumber = 0, IsValid = true,  CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code9, CurrentNumber = 0, IsValid = true,  CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code10, CurrentNumber = 0, IsValid = true,  CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code11, CurrentNumber = 0, IsValid = true,  CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code12, CurrentNumber = 0, IsValid = true, CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code13, CurrentNumber = 0, IsValid = true, CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code14, CurrentNumber = 0, IsValid = true, CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code15, CurrentNumber = 0, IsValid = true, CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code16, CurrentNumber = 0, IsValid = true, CreateBy="Admin",CreateTime=DateTime.Now },
                    new CodingList() { ID = Guid.NewGuid(), Code = Code17, CurrentNumber = 0, IsValid = true, CreateBy="Admin",CreateTime=DateTime.Now },
                };
                List<CodingRule> codingrule = new List<CodingRule>() {
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code, Seq = 1, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.y, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code, Seq = 2, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=8, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code2, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "K", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code2, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.y, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code2, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=6, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code3, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "G", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code3, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.y, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code3, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=6, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code4, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "PO", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code4, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code4, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code5, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "POR", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code5, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code5, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code6, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "SO", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code6, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code6, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code7, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "SOR", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code7, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code7, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code8, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "RK", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code8, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code8, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code9, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "RKR", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code9, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code9, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code10, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "CK", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code10, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code10, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code11, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "CKR", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code11, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code11, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code12, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "ORK", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code12, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code12, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code13, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "OCK", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code13, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code13, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code14, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "SK", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code14, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code14, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code15, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "FK", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code15, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code15, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code16, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "OSK", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code16, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code16, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code17, Seq = 1, CodeRule = CodeRuleEnum.Fixeds, FixedValue = "OFK", FixedRule = null, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code17, Seq = 2, CodeRule = CodeRuleEnum.RuleFixed, FixedValue = null, FixedRule = FixedEnum.yyyyMMdd, GlideLen=null, StartNumber = 1, GlideStep = 1, Glide = "0", },
                        new CodingRule() { ID = Guid.NewGuid(), CodingListId = Code17, Seq = 3, CodeRule = CodeRuleEnum.Serial, FixedValue = null, FixedRule = null,GlideLen=5, StartNumber = 1, GlideStep = 1, Glide = "0", },

                };

                Set<CodingList>().AddRange(codinglist);
                Set<CodingRule>().AddRange(codingrule);

                #endregion

                await SaveChangesAsync();

                SetWorkflowData("采购订单审批", "nERP.Model.Po.Buy, nERP.Model");
                SetWorkflowData("采购退货审批", "nERP.Model.Po.BuyReturn, nERP.Model");
                SetWorkflowData("销售订单审批", "nERP.Model.So.Sale, nERP.Model");
                SetWorkflowData("销售退货审批", "nERP.Model.So.SaleReturn, nERP.Model");
                SetWorkflowData("采购入库审批", "nERP.Model.Wms.BuyInWarehouse, nERP.Model");
                SetWorkflowData("采购退货出库审批", "nERP.Model.Wms.BuyReturnOutWarehouse, nERP.Model");
                SetWorkflowData("销售出库审批", "nERP.Model.Wms.SaleOutWarehouse, nERP.Model");
                SetWorkflowData("销售退货入库审批", "nERP.Model.Wms.SaleReturnInWarehouse, nERP.Model");
                SetWorkflowData("其他入库审批", "nERP.Model.Wms.OtherInWarehouse, nERP.Model");
                SetWorkflowData("其他出库审批", "nERP.Model.Wms.OtherOutWarehouse, nERP.Model");
                SetWorkflowData("收款单审批", "nERP.Model.Fin.Receivable, nERP.Model");
                SetWorkflowData("付款单审批", "nERP.Model.Fin.Payment, nERP.Model");
                SetWorkflowData("其他收入审批", "nERP.Model.Fin.OtherIncome, nERP.Model");
                SetWorkflowData("其他支出审批", "nERP.Model.Fin.OtherOutlay, nERP.Model");
                new Task(() =>
                {
                    var dic0 = new DicDef
                    {
                        DicName = "入库业务类别",
                        DicField_DicDef = new System.Collections.Generic.List<DicField> {
                        new DicField {
                            DicFieldName="盘盈",
                            DicFieldDes="盘盈"
                        },
                        new DicField {
                            DicFieldName="移库",
                            DicFieldDes="移库"
                        },
                        new DicField {
                            DicFieldName="借入",
                            DicFieldDes="借入"
                        },
                        new DicField {
                            DicFieldName="其他入库",
                            DicFieldDes="其他入库"
                        },
                    }
                    };
                    Set<DicDef>().Add(dic0);
                    var dic1 = new DicDef
                    {
                        DicName = "出库业务类别",
                        DicField_DicDef = new System.Collections.Generic.List<DicField> {
                        new DicField {
                            DicFieldName="盘亏",
                            DicFieldDes="盘亏"
                        },
                        new DicField {
                            DicFieldName="移库",
                            DicFieldDes="移库"
                        },
                        new DicField {
                            DicFieldName="借出",
                            DicFieldDes="借出"
                        },
                        new DicField {
                            DicFieldName="其他出库",
                            DicFieldDes="其他出库"
                        },
                    }
                    };
                    Set<DicDef>().Add(dic1);
                    var dic2 = new DicDef
                    {
                        DicName = "结算方式",
                        DicField_DicDef = new System.Collections.Generic.List<DicField> {
                        new DicField {
                            DicFieldName="银行转账",
                            DicFieldDes="银行转账"
                        },
                        new DicField {
                            DicFieldName="支付宝",
                            DicFieldDes="支付宝"
                        },
                        new DicField {
                            DicFieldName="微信",
                            DicFieldDes="微信"
                        },
                        new DicField {
                            DicFieldName="现金",
                            DicFieldDes="现金"
                        },
                    }
                    };
                    Set<DicDef>().Add(dic2);
                    var dic3 = new DicDef
                    {
                        DicName = "其他收入类别",
                        DicField_DicDef = new System.Collections.Generic.List<DicField> {
                        new DicField {
                            DicFieldName="其他",
                            DicFieldDes="其他"
                        },
                    }
                    };
                    Set<DicDef>().Add(dic3);
                    var dic4 = new DicDef
                    {
                        DicName = "其他支出类别",
                        DicField_DicDef = new System.Collections.Generic.List<DicField> {
                        new DicField {
                            DicFieldName="电费",
                            DicFieldDes="电费"
                        },
                        new DicField {
                            DicFieldName="房租",
                            DicFieldDes="房租"
                        },
                        new DicField {
                            DicFieldName="其他",
                            DicFieldDes="其他"
                        },
                    }
                    };
                    Set<DicDef>().Add(dic4);
                    SaveChanges();
                }).Start();
                try
                {
                    Dictionary<string, List<object>> data = new Dictionary<string, List<object>>();
                    new Task(() =>
                    {
                    }).Start();
                }
                catch { }
            }
            return state;
        }

        private void SetWorkflowData(string name, string modelname)
        {
            using (var dc = this.CreateNew())
            {
                dc.Set<Elsa_WorkflowDefinition>().Add(new Elsa_WorkflowDefinition
                {
                    ID = Guid.NewGuid().ToString("N").ToLower(),
                    DefinitionId = Guid.NewGuid().ToString("N").ToLower(),
                    Name = name,
                    Version = 1,
                    PersistenceBehavior = 1,
                    IsPublished = true,
                    IsLatest = true,
                    CreatedAt = DateTime.Now,
                    Data = $@"{{
                      ""$id"": ""1"",
                      ""activities"": [
                        {{
                          ""$id"": ""2"",
                          ""activityId"": ""eb10789a-536b-4335-acfe-ee2bfb888cbc"",
                          ""type"": ""WtmApproveActivity"",
                          ""displayName"": ""审批"",
                          ""persistWorkflow"": false,
                          ""loadWorkflowContext"": false,
                          ""saveWorkflowContext"": false,
                          ""properties"": [
                            {{
                              ""$id"": ""3"",
                              ""name"": ""ApproveUsers"",
                              ""expressions"": {{
                                ""$id"": ""4"",
                                ""Json"": ""[\""admin\""]""
                              }}
                            }},
                            {{
                              ""$id"": ""5"",
                              ""name"": ""ApproveRoles"",
                              ""expressions"": {{
                                ""$id"": ""6""
                              }}
                            }},
                            {{
                              ""$id"": ""7"",
                              ""name"": ""ApproveGroups"",
                              ""expressions"": {{
                                ""$id"": ""8""
                              }}
                            }},
                            {{
                              ""$id"": ""9"",
                              ""name"": ""ApproveManagers"",
                              ""expressions"": {{
                                ""$id"": ""10""
                              }}
                            }},
                            {{
                              ""$id"": ""11"",
                              ""name"": ""ApproveSpecials"",
                              ""expressions"": {{
                                ""$id"": ""12""
                              }}
                            }},
                            {{
                              ""$id"": ""13"",
                              ""name"": ""Tag"",
                              ""expressions"": {{
                                ""$id"": ""14""
                              }}
                            }}
                          ],
                          ""propertyStorageProviders"": {{
                            ""$id"": ""15""
                          }}
                        }},
                        {{
                          ""$id"": ""16"",
                          ""activityId"": ""e52df4f2-2da7-43ac-973a-76618072eec2"",
                          ""type"": ""Finish"",
                          ""displayName"": ""结束"",
                          ""persistWorkflow"": false,
                          ""loadWorkflowContext"": false,
                          ""saveWorkflowContext"": false,
                          ""properties"": [
                            {{
                              ""$id"": ""17"",
                              ""name"": ""ActivityOutput"",
                              ""expressions"": {{
                                ""$id"": ""18""
                              }}
                            }},
                            {{
                              ""$id"": ""19"",
                              ""name"": ""OutcomeNames"",
                              ""expressions"": {{
                                ""$id"": ""20""
                              }}
                            }}
                          ],
                          ""propertyStorageProviders"": {{
                            ""$id"": ""21""
                          }}
                        }}
                      ],
                      ""connections"": [
                        {{
                          ""$id"": ""22"",
                          ""sourceActivityId"": ""eb10789a-536b-4335-acfe-ee2bfb888cbc"",
                          ""targetActivityId"": ""e52df4f2-2da7-43ac-973a-76618072eec2"",
                          ""outcome"": ""同意""
                        }},
                        {{
                          ""$id"": ""23"",
                          ""sourceActivityId"": ""eb10789a-536b-4335-acfe-ee2bfb888cbc"",
                          ""targetActivityId"": ""e52df4f2-2da7-43ac-973a-76618072eec2"",
                          ""outcome"": ""拒绝""
                        }}
                      ],
                      ""variables"": {{
                        ""$id"": ""24"",
                        ""data"": {{}}
                      }},
                      ""contextOptions"": {{
                        ""$id"": ""25"",
                        ""contextType"": ""{modelname}"",
                        ""contextFidelity"": ""Burst""
                      }},
                      ""customAttributes"": {{
                        ""$id"": ""26"",
                        ""data"": {{}}
                      }}
                    }}"
                });
                try
                {
                    dc.SaveChanges();
                }
                catch { }
            }
        }


        private void SetTestData(Type modelType, Dictionary<string, List<object>> data, int count = 100)
        {
            int exist = 0;
            if (data.ContainsKey(modelType.FullName))
            {
                exist = data[modelType.FullName].Count;
                if (exist > 0)
                    return;
            }
            using (var dc = this.CreateNew())
            {
                Random r = new Random();
                data[modelType.FullName] = new List<object>();
                int retry = 0;
                List<string> ids = new List<string>();
                for (int i = 0; i < count - exist; i++)
                {
                    var modelprops = modelType.GetRandomValuesForTestData();
                    var newobj = modelType.GetConstructor(Type.EmptyTypes).Invoke(null);
                    var idvalue = modelprops.Where(x => x.Key == "ID").Select(x => x.Value).SingleOrDefault();
                    if (idvalue != null)
                    {
                        if (ids.Contains(idvalue.ToLower()) == false)
                        {
                            ids.Add(idvalue.ToLower());
                        }
                        else
                        {
                            retry++;
                            i--;
                            if (retry > count)
                            {
                                break;
                            }
                            continue;
                        }
                    }
                    foreach (var pro in modelprops)
                    {
                        if (pro.Value == "$fk$")
                        {
                            var fkpro = modelType.GetSingleProperty(pro.Key[0..^2]);
                            var fktype = fkpro?.PropertyType;
                            if (fktype != modelType && typeof(TopBasePoco).IsAssignableFrom(fktype) == true)
                            {
                                try
                                {
                                    if (fktype == typeof(DicField))
                                    {
                                        var display = fkpro.GetCustomAttributes(typeof(RefDicNameAttribute), true).FirstOrDefault() as RefDicNameAttribute;
                                        if (display != null)
                                        {
                                            var dicfields = Set<DicDef>().Local.Where(x => x.DicName == display.Name).SelectMany(x => x.DicField_DicDef).Select(x => x.ID).ToList();
                                            newobj.SetPropertyValue(pro.Key, dicfields[r.Next(0, dicfields.Count)]);
                                        }
                                    }
                                    else
                                    {
                                        SetTestData(fktype, data, count);
                                        newobj.SetPropertyValue(pro.Key, (data[fktype.FullName][r.Next(0, data[fktype.FullName].Count)] as TopBasePoco).GetID());
                                    }

                                }
                                catch { }
                            }
                        }
                        else
                        {
                            var v = pro.Value;
                            if (v.StartsWith("\""))
                            {
                                v = v[1..];
                            }
                            if (v.EndsWith("\""))
                            {
                                v = v[..^1];
                            }
                            newobj.SetPropertyValue(pro.Key, v);
                        }
                    }
                    if (modelType == typeof(FileAttachment))
                    {
                        newobj.SetPropertyValue("Path", "./wwwroot/logo.png");
                        newobj.SetPropertyValue("SaveMode", "local");
                        newobj.SetPropertyValue("Length", 16728);
                    }
                    if (typeof(IBasePoco).IsAssignableFrom(modelType))
                    {
                        newobj.SetPropertyValue("CreateTime", DateTime.Now);
                        newobj.SetPropertyValue("CreateBy", "admin");
                    }
                    if (typeof(IPersistPoco).IsAssignableFrom(modelType))
                    {
                        newobj.SetPropertyValue("IsValid", true);
                    }
                    try
                    {
                        (dc as DbContext).Add(newobj);
                        data[modelType.FullName].Add(newobj);
                    }
                    catch
                    {
                        retry++;
                        i--;
                        if (retry > count)
                        {
                            break;
                        }
                    }
                }
                try
                {
                    dc.SaveChanges();
                }
                catch { }
            }
        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            var allTypes = Utils.GetAllModels();

            foreach (var item in allTypes)
            {
                if (typeof(TopBasePoco).IsAssignableFrom(item) && item.CustomAttributes.Any(x => x.AttributeType == typeof(MiddleTableAttribute)) == false)
                {
                    var pros = item.GetProperties().Where(x => x.PropertyType == typeof(DicField)).ToList();
                    foreach (var filepro in pros)
                    {
                        var builder = typeof(ModelBuilder).GetMethod("Entity", Type.EmptyTypes).MakeGenericMethod(item).Invoke(modelBuilder, null) as EntityTypeBuilder;
                        try
                        {
                            builder.HasOne(filepro.Name).WithMany(item.Name + "_" + filepro.Name).OnDelete(DeleteBehavior.Restrict);
                        }
                        catch
                        {
                            try
                            {
                                builder.HasOne(filepro.Name).WithMany(item.Name + "_" + filepro.Name.Substring(0, 1).ToLower() + filepro.Name.Substring(1)).OnDelete(DeleteBehavior.Restrict);
                            }
                            catch { }
                        }
                    }
                }
            }
        }
    }

    /// <summary>
    /// DesignTimeFactory for EF Migration, use your full connection string,
    /// EF will find this class and use the connection defined here to run Add-Migration and Update-Database
    /// </summary>
    public class DataContextFactory : IDesignTimeDbContextFactory<DataContext>
    {
        public DataContext CreateDbContext(string[] args)
        {
            return new DataContext("your full connection string", DBTypeEnum.SqlServer);
        }
    }

}